package com.lysb.core.utils;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 签名工具类
 */
@Slf4j
public class SignatureVerificationUtil {
    private final static String SIGN_FIELD = "sign";
    private final static String SIGN_STR_SIGN_KEY = "&sign_key=";
    private final static String CIPHERTEXT_FIELD = "ciphertext";
    private final static String DATA_FIELD = "data";
    private final static String NULL = "null";

    /**
     * 验证签名
     *
     * @param json   参数
     * @param secret 签名秘钥
     * @return true false
     * @throws NoSuchAlgorithmException
     */
    public static boolean verify(String json, String secret) throws IOException, NoSuchAlgorithmException {

        JsonNode obj = JsonUtil.instance().readTree(json);
        String sign = obj.path(SIGN_FIELD).asText();

        String signTmp = sign(json, secret);
        if (signTmp.equalsIgnoreCase(sign)) {
            return true;
        }
        return false;

    }

    public static String sign(String json, String secret) throws IOException, NoSuchAlgorithmException {
        JsonNode obj = JsonUtil.instance().readTree(json);
        SortedMap<String, String> map = getParamSimple(obj);
        map.remove(DATA_FIELD);
        StringBuilder sb = new StringBuilder();
        for (String key : map.keySet()) {
            if (SIGN_FIELD.equals(key)) {
                continue;
            }
            if (StringUtils.isBlank(map.get(key)) || NULL.equals(map.get(key))) {
                continue;
            }
            sb.append(key).append("=").append(map.get(key));
        }
        sb.append(SIGN_STR_SIGN_KEY).append(secret);
        return EncryptUtil.getMD5Str(sb.toString());
    }

    private static SortedMap<String, String> getParamSimple(JsonNode obj) {
        SortedMap<String, String> sortedMap = new TreeMap<>();
        for (Iterator<String> it = obj.fieldNames(); it.hasNext(); ) {
            String name = it.next();
            JsonNode node = obj.get(name);
            if (node.isArray()) {
                sortedMap.put(name, node.toString());
            } else {
                sortedMap.put(name, node.asText());
            }
        }
        return sortedMap;
    }


}
